package com.informatics.polymer.server.opsin;

import java.io.StringBufferInputStream;
import java.sql.SQLException;
import java.util.List;

import nu.xom.Element;

import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IChemFile;
import org.openscience.cdk.interfaces.IChemModel;
import org.openscience.cdk.interfaces.IChemSequence;
import org.openscience.cdk.interfaces.IMolecule;
import org.openscience.cdk.interfaces.IMoleculeSet;
import org.openscience.cdk.io.CMLReader;
import org.openscience.cdk.smiles.SmilesGenerator;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
import org.restlet.Context;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;
import org.restlet.resource.StringRepresentation;
import org.restlet.resource.Variant;

import uk.ac.cam.ch.wwmm.opsin.NameToStructure;

import com.informatics.polymer.server.database.DatabaseInteraction;
/**
 * Substructure search restlet using IUPAC name.
 * @author ed
 * @version 1.0
 */
public class OpsinSubstructureSearchResource extends Resource {
	/**
	 * IUPAC id.
	 */
	private String id;
	public void init(Context context, Request request, Response response){
		super.init(context, request, response);
		getVariants().add(new Variant(MediaType.TEXT_PLAIN));
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	/**
	 * Method allows forms to be posted to restlet.
	 */
	@Override
	public boolean allowPost() {
		return true;
	}
	/**
	 * Constructs a NameToStructureConversionResource.
	 * @param context
	 * @param request
	 * @param response
	 */
	public OpsinSubstructureSearchResource(Context context, Request request, Response response){
		super(context,request,response);
		getVariants().add(new Variant(MediaType.TEXT_PLAIN));
	}
	/**
	 * Method deals with the form posted to the restlet.
	 */
	@Override
	public void post(Representation entity) {
		Form form = new Form(entity); 
		setId(form.getValues("IUPACName"));
		//Need to convert id to CML then to Smile string.
		Element cmlElement = null;
		try {
			NameToStructure nameToStructure = NameToStructure.getInstance();
			cmlElement = nameToStructure.parseToCML(id);
			//System.out.println(id);
		//	System.out.println(cmlElement.toXML());
		} catch (Exception e) {
			e.printStackTrace();
		}
		String finalResult = cmlElement.toXML();
		//Convert cml to smiles string for substructure search.
		StringBufferInputStream r = new StringBufferInputStream(finalResult);
		CMLReader cr = new CMLReader(finalResult);
		try {
			cr.setReader(r);
		} catch (CDKException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		IChemFile chemFile = null;
		try {
			chemFile = (IChemFile) cr.read(new org.openscience.cdk.ChemFile());
		} catch (CDKException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		IChemSequence chemSeq = chemFile.getChemSequence(0);
		IChemModel icm = chemSeq.getChemModel(0);
		IMoleculeSet moleculeSet = icm.getMoleculeSet();
		IMolecule m1 = moleculeSet.getMolecule(0);
		IMolecule mol = (IMolecule) AtomContainerManipulator.removeHydrogens(m1);
		SmilesGenerator gen = new SmilesGenerator();
		gen.setUseAromaticityFlag(true);
		String smilesQuery = gen.createSMILES(mol);
		System.out.println(smilesQuery);
		//Need to remove explicit hydrogens then search will work.
		StringBuffer sb = new StringBuffer();
		DatabaseInteraction databaseInteraction = new DatabaseInteraction();
		try {
			databaseInteraction.init();
			List<com.informatics.polymer.server.database.RepeatUnit> resu = databaseInteraction.getSelectedDBResults(smilesQuery);
			for(com.informatics.polymer.server.database.RepeatUnit ru: resu){
				sb.append(ru.getId()+"\n");}
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 catch (CDKException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			StringRepresentation str = new StringRepresentation(sb);
			getResponse().setEntity(str);

	}

	// Respond to GET
	public Representation represent (Variant variant) throws ResourceException{
		Representation resource = null;
			if (!MediaType.TEXT_PLAIN.includes(variant.getMediaType())) {
				throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE);
			}
			else{
				StringBuffer sb = new StringBuffer();
				try {
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}		
				resource = new StringRepresentation(sb.toString(), MediaType.TEXT_PLAIN); 
				return resource;
			}

	}

}
